using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Xml.Serialization;
using TciNewsReader_2014_04.Infrastructure;
namespace TciNewsReader_2014_04.Model
{
    /// <summary>
    /// Manages the inter-session handling of read items such that items read in a previous session
    /// are recognized and hidden from the view (unless requested)
    /// </summary>
    public static class ItemWrapperHistoryManager
    {
        private static readonly List<ItemWrapperHistory> ItemWrapperHistoryCollection = new List<ItemWrapperHistory>();
        private static readonly XmlSerializer XmlSerializer = new XmlSerializer(typeof(List<ItemWrapperHistory>));
        static ItemWrapperHistoryManager()
        {
            if (File.Exists(Constants.HistoryLocation))
            {
                using (StreamReader sr = new StreamReader(Constants.HistoryLocation))
                {
                    var deserialized = XmlSerializer.Deserialize(sr) as List<ItemWrapperHistory>;
                    if (deserialized != null)
                    {
                        foreach (var d in deserialized)
                        {
                            ItemWrapperHistoryCollection.Add(d);
                        }
                    }
                }
            }
        }
        public static int HistoryCount { get { return ItemWrapperHistoryCollection.Count; } }
        public static void SetStatus(ItemWrapper iw)
        {
            var h = ItemWrapperHistoryCollection.FirstOrDefault(q => q.Md5 == iw.Md5);
            if (h != null)
            {
                iw.ItemStatus = ItemStatus.Read;
            }
        }
        public static void SaveReadItem(ItemWrapper iw)
        {
            if (iw.ItemStatus == ItemStatus.Read)
            {
                ItemWrapperHistory iwh = new ItemWrapperHistory{PubTime = iw.ItemPublishDate, Md5 = iw.Md5};
                if (!ItemWrapperHistoryCollection.Contains(iwh))
                {
                    ItemWrapperHistoryCollection.Add(iwh);
                    SaveStack();
                }
            }
        }
        private static void SaveStack()
        {
            while (ItemWrapperHistoryCollection.Count > Constants.MaxHistoryItems)
            {
                ItemWrapperHistoryCollection.RemoveAt(0);
            }
            using (StreamWriter sw = new StreamWriter(Constants.HistoryLocation))
            {
                XmlSerializer.Serialize(sw, ItemWrapperHistoryCollection);
            }
        }
        /// <summary>
        /// Internal class for serialization.
        /// 
        /// Why MD5?  RSS items can occur in many different languages and character sets.  They also
        /// contain escaped characters and tags and quotation marks.  So to avoid having all of that
        /// travel through a stream reader and serializer, the information is reduced to a common format
        /// which uniquely identifies the item.  Thus MD5.  History items are meant to be used internally
        /// by the app and are not meant for end-user consumption anyway.
        /// </summary>
        public class ItemWrapperHistory:IComparable<ItemWrapperHistory>, IEquatable<ItemWrapperHistory>
        {
            public DateTime PubTime { get; set; }
            public string Md5 { get; set; }
            public int CompareTo(ItemWrapperHistory other)
            {
                return Convert.ToInt32(PubTime.ToOADate() - other.PubTime.ToOADate());
            }
            public bool Equals(ItemWrapperHistory other)
            {
                return Md5 == other.Md5;
            }
        }
    }
}